package com.foodorder.service.impl;

import com.foodorder.entity.DeliveryStaff;
import com.foodorder.entity.DeliveryTracking;
import com.foodorder.repository.DeliveryStaffRepository;
import com.foodorder.repository.DeliveryTrackingRepository;
import com.foodorder.service.DeliveryStaffService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 配送员服务实现类
 */
@Service
public class DeliveryStaffServiceImpl implements DeliveryStaffService {

    private static final Logger log = LoggerFactory.getLogger(DeliveryStaffServiceImpl.class);
    
    @Autowired
    private DeliveryStaffRepository deliveryStaffRepository;
    
    @Autowired
    private DeliveryTrackingRepository deliveryTrackingRepository;
    
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public Optional<DeliveryStaff> findById(Long id) {
        return deliveryStaffRepository.findById(id);
    }

    @Override
    public Optional<DeliveryStaff> findByPhone(String phone) {
        return deliveryStaffRepository.findByPhone(phone);
    }

    @Override
    public Map<String, Object> login(String phone, String password) {
        Map<String, Object> result = new HashMap<>();
        
        Optional<DeliveryStaff> staffOptional = findByPhone(phone);
        if (staffOptional.isEmpty()) {
            result.put("success", false);
            result.put("message", "手机号未注册");
            return result;
        }
        
        DeliveryStaff staff = staffOptional.get();
        
        if (!DeliveryStaff.DeliveryStaffStatus.ACTIVE.equals(staff.getStatus())) {
            result.put("success", false);
            result.put("message", "账号已被锁定或禁用");
            return result;
        }
        
        if (!passwordEncoder.matches(password, staff.getPassword())) {
            result.put("success", false);
            result.put("message", "密码错误");
            return result;
        }
        
        // 更新最后登录时间
        staff.setLastLoginTime(LocalDateTime.now());
        deliveryStaffRepository.save(staff);
        
        // 生成token（实际项目中应使用JWT等）
        String token = UUID.randomUUID().toString();
        
        result.put("success", true);
        result.put("message", "登录成功");
        result.put("token", token);
        result.put("staff", staff);
        
        return result;
    }

    @Override
    public DeliveryStaff save(DeliveryStaff staff) {
        // 如果是新建配送员且密码未加密，则加密密码
        if (staff.getId() == null && !staff.getPassword().startsWith("$2a$")) {
            staff.setPassword(passwordEncoder.encode(staff.getPassword()));
        }
        
        return deliveryStaffRepository.save(staff);
    }

    @Override
    @Transactional
    public DeliveryStaff updateWorkingStatus(Long id, DeliveryStaff.WorkingStatus workingStatus) {
        Optional<DeliveryStaff> staffOptional = deliveryStaffRepository.findById(id);
        if (staffOptional.isEmpty()) {
            throw new IllegalArgumentException("配送员不存在");
        }
        
        DeliveryStaff staff = staffOptional.get();
        staff.setWorkingStatus(workingStatus);
        
        return deliveryStaffRepository.save(staff);
    }

    @Override
    @Transactional
    public DeliveryStaff updateLocation(Long id, BigDecimal latitude, BigDecimal longitude) {
        Optional<DeliveryStaff> staffOptional = deliveryStaffRepository.findById(id);
        if (staffOptional.isEmpty()) {
            throw new IllegalArgumentException("配送员不存在");
        }
        
        DeliveryStaff staff = staffOptional.get();
        staff.setCurrentLatitude(latitude);
        staff.setCurrentLongitude(longitude);
        staff.setLastLocationUpdateTime(LocalDateTime.now());
        
        // 如果配送员正在配送中，同时更新配送订单的当前位置
        if (DeliveryStaff.WorkingStatus.DELIVERING.equals(staff.getWorkingStatus())) {
            deliveryTrackingRepository.findByDeliveryStaffIdAndStatus(
                    id, DeliveryTracking.DeliveryStatus.IN_DELIVERY)
                    .forEach(tracking -> {
                        tracking.setCurrentLatitude(latitude);
                        tracking.setCurrentLongitude(longitude);
                        deliveryTrackingRepository.save(tracking);
                    });
        }
        
        return deliveryStaffRepository.save(staff);
    }

    @Override
    public List<DeliveryStaff> findNearbyAvailableStaff(Long storeId, BigDecimal latitude, BigDecimal longitude, double distance) {
        // 实际项目中应使用地理空间查询来实现
        // 这里简化实现，仅查询可接单的配送员
        return deliveryStaffRepository.findByStoreIdAndWorkingStatus(
                storeId, DeliveryStaff.WorkingStatus.ONLINE);
    }

    @Override
    @Transactional
    public boolean assignOrder(Long orderId, Long staffId) {
        // 查询配送员
        Optional<DeliveryStaff> staffOptional = deliveryStaffRepository.findById(staffId);
        if (staffOptional.isEmpty()) {
            return false;
        }
        
        DeliveryStaff staff = staffOptional.get();
        
        // 检查配送员状态
        if (!DeliveryStaff.WorkingStatus.ONLINE.equals(staff.getWorkingStatus())) {
            return false;
        }
        
        // 查询订单配送记录
        Optional<DeliveryTracking> trackingOptional = deliveryTrackingRepository.findByOrderId(orderId);
        if (trackingOptional.isEmpty()) {
            return false;
        }
        
        DeliveryTracking tracking = trackingOptional.get();
        
        // 检查订单状态
        if (!DeliveryTracking.DeliveryStatus.PENDING.equals(tracking.getStatus())) {
            return false;
        }
        
        // 分配配送员
        tracking.setDeliveryStaffId(staffId);
        tracking.setStatus(DeliveryTracking.DeliveryStatus.ASSIGNED);
        deliveryTrackingRepository.save(tracking);
        
        return true;
    }

    @Override
    @Transactional
    public boolean acceptOrder(Long orderId, Long staffId) {
        // 查询订单配送记录
        Optional<DeliveryTracking> trackingOptional = deliveryTrackingRepository.findByOrderId(orderId);
        if (trackingOptional.isEmpty()) {
            return false;
        }
        
        DeliveryTracking tracking = trackingOptional.get();
        
        // 检查是否分配给该配送员
        if (!staffId.equals(tracking.getDeliveryStaffId())) {
            return false;
        }
        
        // 检查订单状态
        if (!DeliveryTracking.DeliveryStatus.ASSIGNED.equals(tracking.getStatus())) {
            return false;
        }
        
        // 更新配送员状态
        Optional<DeliveryStaff> staffOptional = deliveryStaffRepository.findById(staffId);
        if (staffOptional.isEmpty()) {
            return false;
        }
        
        DeliveryStaff staff = staffOptional.get();
        staff.setWorkingStatus(DeliveryStaff.WorkingStatus.DELIVERING);
        deliveryStaffRepository.save(staff);
        
        // 更新配送记录
        tracking.setStatus(DeliveryTracking.DeliveryStatus.ACCEPTED);
        tracking.setAcceptedTime(LocalDateTime.now());
        deliveryTrackingRepository.save(tracking);
        
        return true;
    }

    @Override
    @Transactional
    public boolean pickupOrder(Long orderId, Long staffId) {
        // 查询订单配送记录
        Optional<DeliveryTracking> trackingOptional = deliveryTrackingRepository.findByOrderId(orderId);
        if (trackingOptional.isEmpty()) {
            return false;
        }
        
        DeliveryTracking tracking = trackingOptional.get();
        
        // 检查是否由该配送员配送
        if (!staffId.equals(tracking.getDeliveryStaffId())) {
            return false;
        }
        
        // 检查订单状态
        if (!DeliveryTracking.DeliveryStatus.ACCEPTED.equals(tracking.getStatus()) &&
            !DeliveryTracking.DeliveryStatus.ARRIVED_AT_STORE.equals(tracking.getStatus())) {
            return false;
        }
        
        // 更新配送记录
        tracking.setStatus(DeliveryTracking.DeliveryStatus.PICKED_UP);
        tracking.setPickupTime(LocalDateTime.now());
        tracking.setStartDeliveryTime(LocalDateTime.now());
        deliveryTrackingRepository.save(tracking);
        
        return true;
    }

    @Override
    @Transactional
    public boolean completeDelivery(Long orderId, Long staffId) {
        // 查询订单配送记录
        Optional<DeliveryTracking> trackingOptional = deliveryTrackingRepository.findByOrderId(orderId);
        if (trackingOptional.isEmpty()) {
            return false;
        }
        
        DeliveryTracking tracking = trackingOptional.get();
        
        // 检查是否由该配送员配送
        if (!staffId.equals(tracking.getDeliveryStaffId())) {
            return false;
        }
        
        // 检查订单状态
        if (!DeliveryTracking.DeliveryStatus.PICKED_UP.equals(tracking.getStatus()) &&
            !DeliveryTracking.DeliveryStatus.IN_DELIVERY.equals(tracking.getStatus())) {
            return false;
        }
        
        // 更新配送员状态
        Optional<DeliveryStaff> staffOptional = deliveryStaffRepository.findById(staffId);
        if (staffOptional.isEmpty()) {
            return false;
        }
        
        DeliveryStaff staff = staffOptional.get();
        staff.setWorkingStatus(DeliveryStaff.WorkingStatus.ONLINE);
        staff.setCompletedOrderCount(staff.getCompletedOrderCount() + 1);
        deliveryStaffRepository.save(staff);
        
        // 更新配送记录
        tracking.setStatus(DeliveryTracking.DeliveryStatus.DELIVERED);
        tracking.setActualDeliveryTime(LocalDateTime.now());
        deliveryTrackingRepository.save(tracking);
        
        return true;
    }
} 